Crate binggan

source ·
Expand description

Binggan (餅乾, bǐng gān, means cookie in Chinese) is a benchmarking library for Rust. It is designed to be simple to use and to provide a good overview of the performance of your code and its memory consumption.

It allows arbitrary named inputs to be passed to the benchmarks.

§Benchmarking

There are 2 main entry points BenchRunner and InputGroup. If you want to run benchmarks with the same inputs, use InputGroup. Otherwise if you need more flexibility you can use BenchGroup via BenchRunner::new_group_with_name.

See https://github.com/PSeitz/binggan/tree/main/benches for examples.

§Example for InputGroup

use binggan::{black_box, InputGroup, PeakMemAlloc, INSTRUMENTED_SYSTEM};

#[global_allocator]
pub static GLOBAL: &PeakMemAlloc<std::alloc::System> = &INSTRUMENTED_SYSTEM;

fn main() {
    // Tuples of name and data for the inputs
    let data = vec![
        (
            "max id 100; 100 el all the same",
            std::iter::repeat(100).take(100).collect(),
        ),
        (   
            "max id 100; 100 el all different",
            (0..100).collect()
        ),
    ];
    bench_group(InputGroup::new_with_inputs(data));
}

// Run the benchmark for the group with input `Vec<usize>`
fn bench_group(mut runner: InputGroup<Vec<usize>>) {
    runner.set_alloc(GLOBAL); // Set the peak mem allocator. This will enable peak memory reporting.
    runner.enable_perf(); // Enable perf integration. This only works on linux.
    runner.register("vec", move |data| {
        test_vec(data);
    });
    runner.register("hashmap", move |data| {
        test_hashmap(data);
    });
   runner.run();
}

fn test_vec(data: &Vec<usize>) {
    let mut vec = Vec::new();
    for idx in data {
        if vec.len() <= *idx {
            vec.resize(idx + 1, 0);
        }
        vec[*idx] += 1;
    }
    black_box(vec);
}
fn test_hashmap(data: &Vec<usize>) {
    let mut map = std::collections::HashMap::new();
    for idx in data {
        *map.entry(idx).or_insert(0) += 1;
    }
    black_box(map);
}

§Example for BenchGroup

use std::collections::HashMap;

use binggan::{black_box, BenchRunner, PeakMemAlloc, INSTRUMENTED_SYSTEM};

#[global_allocator]
pub static GLOBAL: &PeakMemAlloc<std::alloc::System> = &INSTRUMENTED_SYSTEM;

fn test_vec(data: &Vec<usize>) -> Vec<i32> {
    let mut vec = Vec::new();
    for idx in data {
        if vec.len() <= *idx {
            vec.resize(idx + 1, 0);
        }
        vec[*idx] += 1;
    }
    vec
}
fn test_hashmap(data: &Vec<usize>) -> HashMap<&usize, i32> {
    let mut map = std::collections::HashMap::new();
    for idx in data {
        *map.entry(idx).or_insert(0) += 1;
    }
    map
}

fn run_bench() {
    let inputs: Vec<(&str, Vec<usize>)> = vec![
        (
            "max id 100; 100 el all the same",
            std::iter::repeat(100).take(100).collect(),
        ),
        ("max id 100; 100 el all different", (0..100).collect()),
    ];
    let mut runner: BenchRunner = BenchRunner::new();
    runner.set_alloc(GLOBAL); // Set the peak mem allocator. This will enable peak memory reporting.

    runner.config().enable_perf();
    runner.config().set_cache_trasher(true);

    let mut group = runner.new_group();
    for (input_name, data) in inputs.iter() {
        group.set_input_size(data.len() * std::mem::size_of::<usize>());
        group.register_with_input("vec", input_name, data, move |data| {
            black_box(test_vec(data));
        });
        group.register_with_input("hashmap", input_name, data, move |data| {
            black_box(test_hashmap(data));
        });
    }
    group.run();
}

fn main() {
    run_bench();
}

Structs§

  • BenchGroup is a group of benchmarks run together.
  • The main struct to run benchmarks.
  • Configure the benchmarking options.
  • InputGroup is a collection of benchmarks that are run with the same inputs.
  • Input
  • An allocator middleware which keeps track of peak memory consumption.

Statics§

Traits§

  • The PeakAllocTrait trait provides a common interface for all allocators.

Functions§

  • A function that is opaque to the optimizer, used to prevent the compiler from optimizing away computations in a benchmark. An identity function that hints to the compiler to be maximally pessimistic about what black_box could do.